![]() |
Java Database Programming with JDBC
by Pratik Patel Coriolis, The Coriolis Group ISBN: 1576100561 Pub Date: 10/01/96 |
Table of Contents |
If you are already familiar with programming, especially C or C++ programming, this appendix should serve as a good hands-on review. As we discuss Java, well point out the areas in which Java differs from other languages. If you dont have much experience using structured programming languages, this appendix will give you a good overview of the basic components required to make programming languages like Java come alive.
The actual language components featured in this appendix include:
Before we get into the details of each Java language component, lets stand back 10 steps and look at how many of the key language components are used in the context of a Java program. Figure A.1(shown later) presents a complete visual guide. Here, weve highlighted components such as variable declarations, Java keywords, operators, literals, expressions, and control structures.
Figure A.1 A visual guide to the key Java language components.
Figure A.1 Continued
In case youre wondering, the output for this program looks like this:
Hello John my name is Anthony That's not my name! Let's count to ten.... 1 2 3 4 5 6 7 8 9 10 Now down to zero by two. 10 8 6 4 2 0 Finally, some arithmetic: 10 * 3.09 = 30.9 10 * 3.09 = 30 (integer cast) 10 / 3.09 = 3.23625 10 / 3.09 = 3 (integer cast)
The lexical structure of a language refers to the elements of code that make the code easy for us to understand, but have no effect on the compiled code. For example, all of the comments you place in a program to help you understand how it works are ignored by the Java compiler. You could have a thousand lines of comments for a 20-line program and the compiled bytecodes for the program would be the same size if you took out all the comments. This does not mean that all lexical structures are optional. It simply means that they do not effect the bytecodes.
The lexical structures well discuss include:
Comments make your code easy to understand, modify, and use. But adding comments to an application only after it is finished is not a good practice. More often than not, you wont remember what the code you wrote actually does after you get away from it for a while. Unfortunately, many programmers follow this time-honored tradition. We suggest you try to get in the habit of adding comments as you write your code.
Java supports three different types of comment styles. The first two are taken directly from C and C++. The third type of comment is a new one that can be used to automatically create class and method documentation.
Comment Style #1
/* Comments here... */
This style of commenting comes to us directly from C. Everything between the initial slash-asterisk and ending asterisk-slash is ignored by the Java compiler. This style of commenting can be used anywhere in a program, even in the middle of code (not a good idea). This style of commenting is useful when you have multiple lines of comments because your comment lines can wrap from one line to the next, and you only need to use one set of the /* and */ symbols. Examples:
/* This program was written by Joe Smith. It is the greatest program ever written! */ while (i <= /* comments can be placed here */ maxnum) { total += i; i++; }
In the second example, the comment line is embedded within the program statement. The compiler skips over the comment text, and thus the actual line of code would be processed as:
while (i <= maxnum) ...
Programmers occasionally use this style of commenting while they are testing and debugging code. For example, you could comment out part of an equation or expression:
sum = i /* + (base - 10) */ + factor;
Comment Style #2
// Comment here...
This style of commenting is borrowed from C++. Everything after the double slash marks is ignored by the Java compiler. The comment is terminated by a line return, so you cant use multiple comment lines unless you start each line with the double-slash. Examples:
// This program was written by Joe Smith. // It is the greatest program ever written! while (i <= // this won't work maxnum) { total += i; i++; } base = 20; // This comment example also won't work because the Java compiler will treat this second line as a line of code value = 50;
The comment used in the second example wont work like you might intend because the remainder of the line of code would be commented out (everything after i <=). In the third example, the second comment line is missing the starting // symbols, and the Java compiler will get confused because it will try to process the comment line as if it were a line of code. Believe it or not, this type of commenting mistake occurs oftenso watch out for it!
Comment Style #3
/** Doc Comment here... */
This comment structure may look very similar to the C style of commenting, but that extra asterisk at the beginning makes a huge difference. Of course, remember that only one asterisk must be used as the comment terminator. The Java compiler still ignores the comment, but another program called JAVADOC.EXE, which ships with the Java Development Kit, uses these comments to construct HTML documentation files that describe your packages, classes, and methods, as well as all the variables they use.
Lets look at the third style of commenting in more detail. If implemented correctly and consistently, this style of commenting can provide you with numerous benefits. Figure A.2 shows what the output of the JAVADOC program looks like when run on a typical Java source file.
Figure A.2 Sample output from the JAVADOC program.
If you have ever looked at the Java API documentation on Suns Web site, Figure A.2 should look familiar to you. In fact, the entire API documentation was created this way.
JAVADOC will work if you have created comments or not. Figure A.3 shows the output from this simple application:
class HelloWorld { public static void main(String args[]) { System.out.println("Hello World"); } }
Figure A.3 Sample output from the JAVADOC program.
To add a little more information to our documentation, all we have to do is add this third style of comments. If we change the little HelloWorld application and add a few key comments, the code will look like this:
/** * Welcome to HelloWorld * @author Anthony Potts * @version 1.1 * @see java.lang.System */ class helloworld { /** * Main method of helloworld */ public static void main(String args[]) { System.out.println("Hello World!"); } }
If you now run JAVADOC, the browser will display what you see in Figure A.4. As you can see, this gives us much more information. This system is great for producing documentation for public distribution. Just like all comments, though, it is up to you to make sure that the comments are accurate and plentiful enough to be helpful. Table A.1 lists the tags you can use in your class comments.
Figure A.4 The new JAVADOC output.
Tag | Description |
---|---|
@see classname | Adds a hyperlinked See Also to your class; the classname can be any other class |
@see fully-qualified-classname | Also adds a See Also to the class, but this time you need to use a fully qualified class name like java.awt.window |
@see fully-qualified-classname#methodname | Also adds a See Also to the class, but now you are pointing to a specific method within that class |
@version version-text | Adds a version number that you provide; the version number can be numbers or text |
@author author-name | Adds an author entry; you can use multiple author tags |
The tags you can use in your method comments include all of the @see tags as well as the following: | |
@param paramter-name description... | Used to show which parameters the method accepts; multiple @param tags are acceptable |
@return description... | Used to describe what the method returns |
@exception fully-qualified-classname description... | Used to add a throw entry that describes what type of exceptions this method can throw; multiple @exception tags are acceptable |
Identifiers are the names used for variables, classes, methods, packages, and interfaces which allow the compiler to distinguish them. Identifiers in the Java language should always begin with a letter of the alphabet, either upper or lower case. The only exceptions to this rule are the underscore symbol (_) and the dollar sign ($), which may also be used. If you try to use any other symbol or a numeral as the initial character, you will receive an error.
After the initial character, you are allowed to use numbers, but not all symbols. You can also use almost all of the characters from the Unicode character set. If you are not familiar with the Unicode character set or you get errors, we suggest that you stick with the standard alphabetic characters.
The length of an identifier is basically unlimited. We managed to get up to a few thousand characters before we got bored. Its doubtful you will ever need that many characters, but it is nice to know that the Java compiler wont limit you if you want to create long descriptive names. The only limit you may encounter involves creating class names. Since class names are also used as file names, you need to create names that will not cause problems with your operating system or anyone who will be using your program.
You must also be careful not to use any of the special Java keywords listed in the next section. Here are some examples of valid identifiers:
HelloWorld $Money TickerTape _ME2 Chapter3 ABC123
And here are some examples of invalid identifiers:
3rdChapter #Hello -Main
Common Errors When Using Identifiers
As you are defining and using identifiers in your Java programs, you are bound to encounter some errors from time to time. Lets look at some of the more common error messages that the Java compiler displays. Notice that weve included the part of the code that is responsible for generating the error, the error message, and a description of the message so that you can make sense of it.
Code Example:
public class 1test { }
Error Message:
D:\java\lib\test.java:1: Identifier expected.
Description:
An invalid character has been used in the class identifier. You will see this error when the first character is invalid (especially when it is a number).
Code Example:
public class te?st { }
Error Message:
D:\java\lib\test.java:1: '{' Expected
Description:
This is a common error that occurs when you have an invalid character in the middle of an identifier. In this case, the question mark is invalid, so the compiler gets confused where the class definition ends and its implementation begins.
Code Example:
public class #test { }
Error Message:
D:\java\lib\test.java:1: Invalid character in input.
Description:
Here, the error stems from the fact that the initial character is invalid.
Code Example:
public class catch { }
Error Message:
D:\java\lib\test.java:1: Identifier expected.
Description:
This error shows up when you use a protected keyword as an identifier.
In Java, like other languages, there are certain keywords or tokens that are reserved for system use. These keywords cant be used as names for your classes, variables, packages, or anything else. The keywords are used for a number of tasks such as defining control structures (if, while, and for) and declaring data types (int, char, and float). Table A.2 provides the complete list of Java keywords.
Keyword | Description |
---|---|
abstract | Class modifier |
boolean | Used to define a boolean data type |
break | Used to break out of loops |
byte | Used to define a byte data type |
byvalue * | Not implemented yet |
cast | Used to translate from type to type |
catch | Used with error handling |
char | Used to define a character data type (16-bit) |
class | Used to define a class structure |
const * | Not implemented yet |
continue | Used to continue an operation |
default | Used with the switch statement |
do | Used to create a do loop control structure |
Double | Used to define a floating-point data type (64-bit) |
else | Used to create an else clause for an if statement |
extends | Used to subclass |
final | Used to tell Java that this class can not be subclassed |
finally | Used with exceptions to determine the last option before exiting; it guarantees that code gets called if an exception does or does not happen |
float | Used to define a floating-point data type (32-bit) |
for | Used to create a for loop control structure |
future * | Not implemented yet |
generic * | Not implemented yet |
goto * | Not implemented yet |
if | Used to create an if-then decision-making control structure |
implements | Used to define which interfaces to use |
import | Used to reference external Java packages |
inner | Used to create control blocks |
instanceof | Used to determine if an object is of a certain type |
int | Used to define an integer data type (32-bit values) |
interface | Used to tell Java that the code that follows is an interface |
interfacelong | Used to define an integer data type (64-bit values) |
native | Used when calling external code |
new | Operator used when creating an instance of a class (an object) |
null | Reference to a non-existent value |
operator * | Not implemented yet |
outer | Used to create control blocks |
package | Used to tell Java what package the following code belongs to |
private | Modifier for classes, methods, and variables |
protected | Modifier for classes, methods, and variables |
public | Modifier for classes, methods, and variables |
rest * | Not implemented yet |
return | Used to set the return value of a class or method |
short | Used to define an integer data type (16-bit values) |
static | Modifier for classes, methods, and variables |
super | Used to reference the current class parent class |
switch | Block statement used to pick from a group of choices |
synchronized | Modifier that tells Java that only one instance of a method can be run at one time; it keeps Java from running the method a second time before the first is finished; it is especially useful when dealing with files to avoid conflicts |
this | Used to reference the current object |
throw | Statement that tells Java what exception to pass on an error |
transient | Modifier that can access future Java code |
try | Operator that is used to test for exceptions in code |
var * | Not implemented yet |
void | Modifier for setting the return value of a class or method to nothing |
volatile | Variable modifier |
while | Used to create a while loop control structure |
The words marked with an asterisk (*) are not currently used in the Java language, but you still cant use them to create your own identifiers. More than likely, they will be used as keywords in future versions of the Java language.
Literals are the values that you assign when entering explicit values. For example, in an assignment statement like this the value 10 is a literal. But do not get literals confused with types. Even though they usually go hand in hand, literals and types are not the same.
i = 10;
Types are used to define what type of data a variable can hold, while literals are the values that are actually assigned to those variables.
Literals come in three flavors: numeric, character, and boolean. Boolean literals are simply True and False.
Numeric Literals
Numeric literals are just what they sound likenumbers. We can further subdivide the numeric literals into integers and floating-point literals.
Integer literals are usually represented in decimal format, although you can use the hexadecimal and octal format in Java. If you want to use the hexadecimal format, your numbers need to begin with an 0x or 0X. Octal integers simply begin with a zero (0).
Integer literals are stored differently depending on their size. The int data type is used to store 32-bit integer values ranging from -2,147,483,648 to 2,147,483,648 (decimal). If you need to use even larger numbers, Java switches over to the long data type, which can store 64 bits of information for a range of - 9.223372036855e+18 to 9.223372036855e+18. This would give you a number a little larger than 9 million trillionenough to take care of the national debt! To specify a long integer, you will need to place an l or L at the end of the number. Dont get confused by our use of the terms int and long. There are many other integer data types used by Java, but they all use int or long literals to assign values. Table A.3 provides a summary of the two integer literals.
Integer Literals Ranges | Negative Minimum | Positive Maximum |
---|---|---|
int data type | -2,147,483,648 | 2,147,483,648 |
long data type | -9.223372036855e+18 | 9.223372036855e+18 |
Here are some examples of how integer literals can be used to assign values in Java statements:
int i; i = 1; // All of these literals are of the integer type i= -9; i = 1203131; i = 0xA11; // Using a hexadecimal literal i = 07543; // Using an octal literal i = 4.5; // This would be illegal because a floating-point // literal can't be assigned to an integer type long lg; lg = 1L; // All of these literals are of the long // integer type lg = -9e15; lg = 7e12;
The other type of numeric literal is the floating-point literal. Floating-point values are any numbers that have anything to the right of the decimal place. Similar to integers, floating-point values have 32-bit and 64-bit representations. Both data types conform to IEEE standards. Table A.4 provides a summary of the two floating-point literals.
Floating-Point Ranges | Negative Minimum | Positive Maximum |
---|---|---|
float data type | 1.40239846e-45 | 3.40282347e38 |
double data type | 4.94065645841246544e-324 | 1.79769313486231570e308 |
Here are some examples of how floating-point literals can be used to assign values in Java statements:
float f; f = 1.3; // All of these literals are of the floating-point // type float (32-bit) f = -9.0; f = 1203131.1241234; double d; d = 1.0D; // All of these literals are of the floating- // point type double(32-bit) d = -9.3645e235; d = 7.0001e52D;
Character Literals
The second type of literal that you need to know about is the character literal. Character literals include single characters and strings. Single character literals are enclosed in single quotation marks, while string literals are enclosed in double quotes.
Single characters can be any one character from the Unicode character set. There are also a few special two-character combinations that are non-printing characters but which perform important functions. Table A.5 shows these special combinations.
Character Combination | Standard Designation | Description |
---|---|---|
\ | <newline> | Continuation |
\n | NL or LF | New Line |
\b | BS | Backspace |
\r | CR | Carriage Return |
\f | FF | Form Feed |
\t | HT | Horizontal Tab |
\\ | \ | Backslash |
\ | | Single Quote |
\ | | Double Quote |
\xdd | 0xdd | Hex Bit Pattern |
\ddd | 0ddd | Octal Bit Pattern |
\uddd | 0xdddd | Unicode Character |
The character combinations from Table A.5 also apply to strings. Here are some examples of how character and string literals can be used in Java statements:
char ch; ch = 'a'; // All of these literals are characters ch = \n; // Assign the newline character ch = \'; // Assign a single quote ch = \x30; // Assign a hexadecimal character code String str; str = "Java string";
Operators are used to perform computations on one or more variables or objects. You use operators to add values, compare the size of two numbers, assign a value to a variable, increment the value of a variable, and so on. Table A.6 lists the operators used in Java. Later in this appendix, well explain in detail how each operator works, and well also explain operator precedence.
Operator | Description |
---|---|
+ | Addition |
- | Subtraction |
* | Multiplication |
/ | Division |
% | Modulo |
++ | Increment |
| Decrement |
> | Greater than |
>= | Greater than or equal to |
< | Less than |
<= | Less than or equal to |
== | Equal to |
!= | Not equal to |
! | Logical NOT |
&& | Logical AND |
|| | Logical OR |
& | Bitwise AND |
^ | Bitwise exclusive OR |
| | Bitwise OR |
~ | Bitwise complement |
<< | Left shift |
>> | Right shift |
>>> | Zero fill right shift |
= | Assignment |
+= | Assignment with addition |
-= | Assignment with subtraction |
*= | Assignment with multiplication |
/= | Assignment with division |
%= | Assignment with modulo |
&= | Assignment with bitwise AND |
|= | Assignment with bitwise OR |
^= | Assignment with bitwise exclusive OR |
<<= | Assignment with left shift |
>>= | Assignment with right shift |
>>>= | Assignment with zero fill right shift |
Separators are used in Java to delineate blocks of code. For example, you use curly brackets to enclose a methods implementation, and you use parentheses to enclose arguments being sent to a method. Table A.7 lists the seperators used in Java.
Separator | Description |
---|---|
( ) | Used to define blocks of arguments |
[ ] | Used to define arrays |
{ } | Used to hold blocks of code |
, | Used to separate arguments or variables in a declaration |
; | Used to terminate lines of contiguous code |
Many people confuse the terms types and variables, and use them synonymously. They are, however, not the same. Variables are basically buckets that hold information, while types describe what type of information is in the bucket.
A variable must have both a type and an identifier. Later in this appendix we will cover the process of declaring variables. For now, we just want to guide you through the details of how to decide which types to use, and how to use them properly.
Similar to literals, types can be split into several different categories, including the numeric typesbyte, short, int, long, float, and doubleand the char and boolean types. We will also discuss the string type. Technically, the string type is not a typeit is a class. However, it is used so commonly that we decided to include it here.
All of the integer numeric types use signed twos-complement integers for storing data. Table A.8 provides a summary of the ranges for each of the key Java datatypes.
Data Type | Negative Minimal | Positive Maximal |
---|---|---|
byte | -256 | 255 |
short | -32768 | 32767 |
int | -2147483648 | 2147483647 |
long | -9223372036854775808 | 9223372036854775807 |
float | 1.40239846e-45 | 3.40282347e38 |
double | 4.94065645841246544e-324 | 1.79769313486231570e308 |
boolean | False | True |
The byte type can be used for variables whose value falls between -256 and 255. byte types have an 8-bit length. Here are some examples of byte values:
-7 5 238
The short numeric type can store values ranging from -32768 to 32767. It has a 16-bit depth. Here are some examples:
-7 256 -29524
The int data type takes the short type to the next level. It uses a 32-bit signed integer value that takes our minimal and maximal value up to over 2 billion. Because of this tremendous range, it is one of the most often used datatypes for integers.
Often, unskilled programmers will use the int datatype even though they dont need the full resolution that this datatype provides. If you are using smaller integers, you should consider using the short data type. The rule of thumb to follow is if you know exactly the range of values a certain variable will store, use the smallest datatype possible. This will let your program use less memory and therefore run faster, especially on slower machines or machines with limited RAM.
Here are some examples of int values:
-7 256 -29523234 1321412422
The long data type is the mother of all integer types. It uses a full 64-bit data path to store values that reach up to over 9 million trillion. But be extremely careful when using variables of the long type. If you start using too many of them, or God forbid, an array of longs, you can quickly eat up a ton of resources.
Tip: The danger of using long.
Java provides useful garbage collection tools, so when you are done with these large data types, they will be disposed of and their resources reclaimed. But if you are creating large arrays of long integers, you could really be asking for trouble. For example, if you created a two-dimensional array of long integers that had a 100x100 grid, you would be using up about 100 kilobytes of memory.
Here are some examples of long values:
-7 256 -29523234 1.835412e15 -3e18
The float data type is one of two types used to store floating-point values. The float type is compliant with the IEEE 754 conventions. The floating-point types of Java can store gargantuan numbers. We do not have enough room on the page to physically show you the minimal and maximal values the float data type can store, so we will use a little bit of tricky sounding lingo taken from the Java manual:
The finite nonzero values of type float are of the form s * m * 2e, where s is +1 or -1, m is a positive integer less than 2^24 and e is an integer between -149 and 104, inclusive.
Whew, thats a mouthful. Here are a few examples to show you what the float type might look like in actual use:
-7F 256.0 -23e34 23e100
As if the float type could not hold enough, the double data type gives you even bigger storage space. Lets look again at Suns definition of the possible values for a double:
The finite nonzero values of type float are of the form s * m * 2e, where s is +1 or -1, m is a positive integer less than 2^53 and e is an integer between -1045 and 1000, inclusive.
Again, you can have some truly monstrous numbers here. But when you start dealing with hardcore programming, this type of number becomes necessary from time to time, so it is wise to understand its ranges. Here are a few examples:
-7.0D 256.0D -23e424 23e1000
In other languages, the boolean data type has been designated by an integer with a nonzero or zero value to represent True and False, respectively. This method works well because it gives the user the ability to check for all kinds of values and perform expressions like this:
x=2; if x then...
This can be handy when performing parsing operations or checking string lengths. In Java, however, the boolean data type has its own True and False literals that do not correspond to other values. In fact, as you will learn later in this appendix, Java does not even allow you to perform casts between the boolean data type and any others. There are ways around this limitation, and we will discuss them when we talk about conversion methods.
The char data type is used to store single characters. Since Java uses the Unicode character set, the char type needs to be able to store thousands of characters, so it uses a 16-bit signed integer. The char data type has the ability to be cast or converted to almost all of the others, as we will show you in the next section.
The string type is actually not a primitive data type; it is a class all its own. We decided to talk a little about it here because it is so commonly used that it might as well be considered a primitive. In C and C++, strings are stored in arrays of chars. Java does not use the char type for this, but instead has created its own class that handles strings.
One big advantage to using a class instead of an array of char types is that we are more or less unlimited in the amount of information we can place in a string variable. In C++, the array of chars was limited; now that limitation is taken care of within the class, where we do not care how it is handled.
Declaring variables in Java is very similar to declaring variables in C/C++, as long as you are using the primitive data types. As we said before, almost everything in Java is a classexcept the primitive data types. Lets look at how primitive data types are declared.
Here is what a standard declaration for a primitive variable might look like:
int i;
We have just declared a variable i to be an integer. Here are a few more examples:
byte i, j; int a=7, b = a; float f = 1.06; String name = "Tony";
These examples illustrate some of the things you can do while declaring variables. Lets look at each one individually.
int i;
This is the most basic declaration, with the data type followed by the variable you are declaring.
byte i, j;
In this example, we are declaring two byte variables at one time. There is no limit to the number of variables you can declare this way. All you have to do is add a comma between each variable you wish to declare of the given type, and Java takes care of it for you.
You also have the ability to assign values to variables as you declare them. You can even use a variable you are declaring as part of an expression for the declaration of another variable in the same line. Before we confuse you more, here is an example:
int i = 1; int j = i, k= i + j;
Here we have first declared a variable i as int and assigned it a value of 1. In the next line, we start by declaring a variable j to be equal to i. This is perfectly legal. Next, on the same line, we declare a variable k to be equal to i plus j. Once again, Java handles this without a problem. We could even shorten these two statements to one line like this:
int i = 1, j = i, k= i + j;
One thing to watch out for is using variables before they have been declared. Heres an example:
int j = i, k= i + j; // i is not defined yet int i = 1;
This would cause an undefined variable error because Java does not know to look ahead for future declarations. Lets look at another example:
float f = 1.06;
Does this look correct? Yes, but its not. This is a tricky one. By default, Java assumes that numbers with decimal points are of type double. So, when you try and declare a float to be equal to this number, you receive the following error:
Incompatible type for declaration. Explicit cast needed to convert double to float.
Sounds complicated, but all this error message means is that you need to explicitly tell Java that the literal value 1.06 is a float and not a double. There are two ways to accomplish this. First, you can cast the value to a float like this:
float f = (float)1.06;
This works fine, but it can get confusing. Java also follows the convention used by other languages of placing an f at the end of the literal value to indicate explicitly that it is a float. This also works for the double data type, except that you would use a d. (By the way, capitalization of the f and d does not make a difference.)
float f = 1.06f; double d = 1.06d;
You should realize that the d is not needed in the double declaration because Java assumes it. However, it is better to label all of your variables when possible, especially if you are not sure.
Its difficult to imagine creating any large application or applet without having an array or two. Java uses arrays in a much different manner than other languages. Instead of being a structure that holds variables, arrays in Java are actually objects that can be treated just like any other Java object.
The powerful thing to realize here is that because arrays are objects that are derived from a class, they have methods you can call to retrieve information about the array or to manipulate the array. The current version of the Java language only supports the length method, but you can expect that more methods will be added as the language evolves.
One of the drawbacks to the way Java implements arrays is that they are only one-dimensional. In most other languages, you can create a two-dimensional array by just adding a comma and a second array size. In Java, this does not work. The way around this limitation is to create an array of arrays. Because this is easy to do, the lack of built-in support for multi-dimensional arrays shouldnt hold you back.
Since arrays are actually instances of classes (objects), we need to use constructors to create our arrays much like we did with strings. First, we need to pick a variable name, declare it as an array object, and specify which data type the array will hold. Note that an array can only hold a single data typeyou cant mix strings and integers within a single array. Here are a few examples of how array variables are declared:
int intArray[]; String Names[];
As you can see, these look very similar to standard variable declarations, except for the brackets after the variable name. You could also put the brackets after the data type if you think this approach makes your declarations more readable:
int[] intArray; String[] Names;
There are three ways to set the size of arrays. Two of them require the use of the new operator. Using the new operator initializes all of the array elements to a default value. The third method involves filling in the array elements with values as you declare it.
The first method involves taking a previously declared variable and setting the size of the array. Here are a few examples:
int intArray[]; // Declare the arrays String Names[]; intArray[] = new int[10]; // Size each array Names[] = new String[100];
Or, you can size the array object when you declare it:
int intArray[] = new int[10]; String Names[] = new String[100];
Finally, you can fill in the array with values at declaration time:
String Names[] = {"Tony", "Dave", "Jon", "Ricardo"}; int[] intArray = {1, 2, 3, 4, 5};
Now that you know how to initialize arrays, youll need to learn how to fill them with data and then access the array elements to retrieve the data. We showed you a very simple way to add data to arrays when you initialize them, but often this just is not flexible enough for real-world programming tasks. To access an array value, you simply need to know its location. The indexing system used to access array elements is zero-based, which means that the first value is always located at position 0. Lets look at a little program that first fills in an array and then prints it out:
public class powersOf2 { public static void main(String args[]) { int intArray[] = new int[20]; for (int i = 0; i < intArray.length; i++) { intArray[i] = 1; for(int p = 0; p < i; p++) intArray[i] *= 2 ; } for (int i = 0; i < intArray.length; i++) System.out.println("2 to the power of " + i + " is " + intArray[i]); } }
The output of this program looks like this:
2 to the power of 0 is 1 2 to the power of 1 is 2 2 to the power of 2 is 4 2 to the power of 3 is 8 2 to the power of 4 is 16 2 to the power of 5 is 32 2 to the power of 6 is 64 2 to the power of 7 is 128 2 to the power of 8 is 256 2 to the power of 9 is 512 2 to the power of 10 is 1024 2 to the power of 11 is 2048 2 to the power of 12 is 4096 2 to the power of 13 is 8192 2 to the power of 14 is 16384 2 to the power of 15 is 32768 2 to the power of 16 is 65536 2 to the power of 17 is 131072 2 to the power of 18 is 262144 2 to the power of 19 is 524288
So, how does the program work? We first create our array of integer values and assign it to the intArray variable. Next, we begin a loop that goes from zero to intArray.length. By calling the length method of our array, we find the number of indexes in the array. Then, we start another loop that does the calculation and stores the result in the index specified by the i variable from our initial loop.
Now that we have filled in all the values for our array, we need to step back through them and print out the result. We could have just put the print statement in the initial loop, but the approach we used gives us a chance to use another loop that references our array.
Here is the structure of an index call:
arrayName[index];
Pretty simple. If you try and use an index that is outside the boundaries of the array, a run-time error occurs. If we change the program to count to an index of 21, instead of the actual array length of 20, we would end up getting an error message like this:
java.lang.ArrayIndexOutOfBoundsException: 20 at powersOf2.main(powersOf2.java:10)
This is a pretty common error in any programming language. You need to use some form of exception handling to watch for this problem, unless, of course, you are positive you can create code that never does this (in your dreams).
Multidimensional arrays are created in Java by using arrays of arrays. Here are a few examples of how you can implement multidimensional arrays:
int intArray[][]; String Names[][];
We can even do the same things we did with a single dimension array. We can set the array sizes and even fill in values while we declare the arrays:
int intArray[][] = new int[10][5]; String Names[][] = new String[25][3]; int intArray[][] = {{2, 3, 4} {1, 2, 3}}; String Names[][] = {{"Jon", "Smith"}{"Tony", "Potts"}{"Dave", "Friedel"}};
We can also create arrays that are not rectangular in nature. That is, each array within the main array can have a different number of elements. Here are a few examples:
int intArray[][] = {{1, 2} {1, 2, 3} {1, 2, 3, 4}}; String Names[][] = {{"Jon", "Smith"} {"Tony","A", "Potts"} {"Dave", "H", "Friedel", "Jr."}};
Accessing the data in a multidimensional array is not much more difficult than accessing data in a single-dimensional array. You just need to track the values for each index. Be careful though, as you add dimensions, it becomes increasingly easy to create out of bounds errors. Here are a few examples of how you can declare multidimensional arrays, assign values, and access array elements:
int intArray[][] = new int[10][5]; // Declare the arrays String Names[][] = new String[25][3]; intArray[0][0] = 5; // Assign values intArray[7][2] = 37; intArray[7][9] = 37; // This will cause an out of bounds error! Names[0][0] = "Bill Gates"; // Access an array element in a Java statement System.out.println(Names[0][0]);
Programming with command-line arguments is not a topic youd typically expect to see in an appendix on basic data types and variable declarations. However, because weve been using command-line arguments with some of the sample programs weve been introducing, we thought it would be important to discuss how this feature works in a little more detail.
Command-line arguments are only used with Java applications. They provide a mechanism so that the user of an application can pass in information to be used by the program. Java applets, on the other hand, read in parameters using HTML tags. Command-line arguments are common with languages like C and C++, which were originally designed to work with command-line operating systems like Unix.
The advantage of using command-line arguments is that they are passed to a program when the program first starts, which keeps the program from having to query the user for more information. Command-line arguments are great for passing custom initialization data.
The syntax for passing arguments themselves to a program is extremely simple. Just start your programs as you usually would and then add any number of arguments to the end of the line, with each one separated by a space. Here is a sample call to a program named myApp:
Java myApp open 640 480
In this case, we are calling the Java run-time interpreter and telling it to run the class file myApp. We then are passing in three arguments: open, 640, and 480.
If you wanted to pass in a longer string with spaces as an argument, you could. In this case, you enclose the string in quotation marks and Java will treat it as a single argument. Here is an example:
Java myApp "Nice program!" "640x480"
Once again, the name of the program is myApp. This time, however, we are only sending it two arguments: Nice program! and 640x480. Note that the quotes themselves are not passed, just the string between the quotes.
Now that we know how to pass arguments, where are they stored? How can we see them in our application? If youll recall, all applications have a main() method. You should also notice that this method has an interesting argument structure:
public static void main(String args[]) { ... }
Here, main() indicates that it takes an array named args[] of type String. Java takes any command-line arguments and puts them into the args[] string array. The array is dynamically resized to hold just the number of arguments passed, or zero if none are passed. Note that the use of the args identifier is completely arbitrary. You can use any word you want as long as it conforms to the Java naming rules. You can even get a little more descriptive, like this:
public static void main(String commandLineArgumentsArray[]) { ...
That may be a bit much, but you will never get confused as to what is in the array!
Once weve passed in the arguments to an application and we know where they are stored, how do we get to them? Since the arguments are stored in an array, we can access them just like we would access strings in any other array. Lets look at a simple application that takes two arguments and prints them out:
class testArgs { public static void main(String args[]) { System.out.println(args[0]); System.out.println(args[1]); } }
If we use this command-line statement to run the application
java testArgs hello world
wed get this output:
hello world
Now, try this command line:
java testArgs onearg
Here is the result:
onearg java.lang.ArrayIndexOutOfBoundsException: 1 at testArgs.main(testArgs.java:4)
What happened? Since we were only passing a single argument, the reference to args[1] is illegal and produces an error.
So, how do we stop from getting an error? Instead of calling each argument in line, we can use a for loop to step through each argument. We can check the args.length variable to see if we have reached the last item. Our new code will also recognize if no arguments have been passed and will not try and access the array at all. Enough talking, here is the code:
class testArgs { public static void main(String args[]) { for (int i = 0; i < args.length; i++) { System.out.println(args[i]); } } }
Now, no matter how many arguments are passed (or none), the application can handle it.
Tip: Indexing command-line arguments.
Dont forget that Java arrays are zero-based, so the first command-line argument is stored at position 0, not position 1. This is different than some other languages, like C, where the first argument would be at position 1. In C, position 0 would store the name of the program.
One more thing we should cover here is how to deal with numeric arguments. If you remember, all arguments are passed into an array of strings, so we need to convert those values into numbers.
This is actually very simple. Each data type has an associated class that provides methods for dealing with that data type. Each of these classes has a method that creates a variable of that type from a string. Table A.9 presents a list of those methods.
Class | Method | Return |
---|---|---|
Integer | parseInt(String) | An integer value |
Integer | valueOf(String) | An Integer object initialized to the value represented by the specified String |
Long | parseLong(String) | A long value |
Long | valueOf(String) | A Long object initialized to the value represented by the specified String |
Double | valueOf(String) | A Double object initialized to the value represented by the specified String |
Float | valueOf(String) | A Float object initialized to the value represented by the specified String |
Make sure you understand the difference between the parse*() methods and the valueOf() methods. The parsing methods just return a value that can be plugged into a variable or used as part of an expression. The valueOf() methods return an object of the specified type that has an initial value equal to the value of the string.
/** * Sample Java Application * @author Anthony Potts * @version 1.0 */ class Test extends Object { // Begin Test class // Define class variables static int i = 10; static final double d = 3.09; /* The main() method is automatically called when the program is run. Any words typed after the program name when it is run are placed in the args[] variable, which is an array of strings. For this program to work properly, at least one word must be typed after the program name or else an error will occur. */ public static void main(String args[]) { Test thisTest = new Test(); // Create instance (object) of class String myName = "Anthony"; boolean returnValue; System.out.println("Hello " + args[0] + " my name is " + myName); if(thisTest.sameName(args[0], myName)) { System.out.println("Your name is the same as mine!"); } else { System.out.println("That's not my name!"); } System.out.println("Let's count to ten...."); for (int x = 1; x < 11; x++) { System.out.print(x + " "); } variable declarations while control statement method modifier System.out.println("\nNow down to zero by two."); while ( i > -1) { System.out.print(i + " "); i -= 2; } System.out.println("\nFinally, some arithmetic:"); thisTest.doArithmetic(); } // This method compares the two names sent to it and // returns true if they are the same and false if they are not public boolean sameName(String firstName, String secondName) { if (firstName.equals(secondName)) { return true; } else { return false; } } // This method performs a few computations and prints the result public void doArithmetic(){ i = 10; System.out.println(i + " * " + d + " = " + (i * d)); System.out.println(i + " * " + d + " = " + (int)(i * d) + " (Integer)"); System.out.println(i + " / " + d + " = " + (i / d)); System.out.println(i + " / " + d + " = " + (int)(i / d) + " (Integer)"); } } // End of class
Table of Contents |